/*
 * net_event.cpp
 *
 *  Created on: 2012-7-5
 *      Author: ThinkPad
 */

#include "net_event.h"

net_event::net_event(void)
{
    	op_event = NULL;
    	event_queue_size = DFLT_MIN_CONN_SIZ;  /*default event queue size*/
}

net_event::~net_event(void)
{
    evt_lock.Lock();
    {
            while(free_queue.size()>0)
            {
                    io_event * evt  = free_queue.top();
                    free_queue.pop();

                    if(evt != NULL)
                    {
                            evt->p_conn = NULL;
                            delete evt;
                    }
            }

            while(event_queue.size()>0)
            {
                    io_event * evt  = event_queue.front();
                    event_queue.pop();
                    if(evt != NULL)
                    {
                            evt->p_conn = NULL;
                            delete evt;
                    }
            }

            evt_lock.Unlock();
    }
}

/*
*
*init event queue
*/
int net_event::init_queue(int size)
{
	int ret = FAILURE;
	event_queue_size = size;
    evt_lock.Lock();
    {
    		ret = add_event_queue_pool();
            evt_lock.Unlock();
    }
    return ret;
}

/**
 * add event queue pool,no lock
 */
int net_event::add_event_queue_pool()
{
	    for(int i=0; i < event_queue_size; i++)
		{
				/*io event*/
				io_event *new_event = new io_event();
				if(new_event == NULL)
				{
						return FAILURE;
				}
				new_event->io_evt = EVENT_INVALID;
				new_event->p_conn = NULL;
				free_queue.push(new_event);
		}

	    return SUCCESS;
}

/*
*event enter queue
*/
int net_event::event_enqueue(EVENT io_evt,void *pcon)
{
    evt_lock.Lock();
    {
            if(pcon == NULL)
            {
                    evt_lock.Unlock();
                    return FAILURE;
            }

            /**check free pool size**/
            if(free_queue.size()  < 10)
            {
            		int ret = this->add_event_queue_pool();
            		if(ret != SUCCESS)
            		{
            			   evt_lock.Unlock();
            			   return FAILURE;
            		}
            }

            /*new event data*/
            if(free_queue.size()  > 0)
            {
                    op_event = free_queue.top();
                    free_queue.pop();
            }
            if(op_event == NULL)
            {
                    evt_lock.Unlock();
                    return FAILURE;
            }
            op_event->io_evt = io_evt;
            op_event->p_conn = pcon;

            event_queue.push(op_event);
            op_event = NULL;

            evt_lock.Unlock();
    }
    return SUCCESS;
}

/*
*
*event delete queue
*/
int net_event::event_dequeue(EVENT *evt,void **pcon)
{
    evt_lock.Lock();
    {
            if(event_queue.size() == 0)
            {
                    evt_lock.Unlock();
                    return FAILURE;
            }

            op_event = event_queue.front();
            event_queue.pop();

            if(op_event == NULL)
            {
                    evt_lock.Unlock();
                    return FAILURE;
            }

            *evt = op_event->io_evt;
            *pcon = op_event->p_conn;
            /*return to free pool*/
            op_event->io_evt = EVENT_INVALID;
            op_event->p_conn = NULL;
            free_queue.push(op_event);
            op_event = NULL;

            evt_lock.Unlock();
    }
    return SUCCESS;
}
/*
*current event count
*/
int net_event::get_event_count()
{
    return (int)event_queue.size();
}
